package com.jielin.handling.third.xsky.demo;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.services.s3.model.*;
import com.jielin.handling.third.xsky.XskyS3Basic;
import com.jielin.handling.third.xsky.XskyS3Bucket;
import com.jielin.handling.third.xsky.XskyS3Object;
import com.jielin.handling.util.ConstantUtil;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

public class XSKYS3Service {
    private static String bucketName = "jielin-bucket";
    private static String UploadFile = "/data/xsky.conf";
    private static String fileKey = "abcd";
    public static XskyS3Basic basic = null;
    public static XskyS3Bucket S3Bucket = null;
    public static XskyS3Object S3Object = null;

    static {
        // 创建连接
        basic = new XskyS3Basic(ConstantUtil.XSKY_SERVER_URL);
        S3Bucket = new XskyS3Bucket(basic.client);
        S3Object = new XskyS3Object(basic.client);
    }

    public static void main(String[] args) {
        XSKYS3Service.show();
    }

    public static void uploadObject(String bucketName, String key, File file) throws Exception {
        isExistBucket(bucketName);
        PutObjectResult result = S3Object.PutObject(bucketName, key, file);
        System.out.println(result);
    }

    public static void uploadObject(String bucketName, String key, String content) throws SdkClientException {
        isExistBucket(bucketName);
        PutObjectResult result = S3Object.PutObject(bucketName, key, content);
        System.out.println(result);
    }

    public static void uploadObjectThrows(String bucketName, String key, File file) throws SdkClientException {
        isExistBucket(bucketName);
        PutObjectResult result = S3Object.PutObjectThrows(bucketName, key, file);
        System.out.println(result);
    }

    public static void downloadObject(String bucketName, String key, String newFile) throws Exception {
        isExistBucket(bucketName);
        S3Object s3object = S3Object.getObject(bucketName, key);
        XskyS3Basic.WriteNewFile(s3object.getObjectContent(), newFile);
        s3object.close();
    }

    public static void deleteObject(String bucketName, String key) throws Exception {
        isExistBucket(bucketName);
        S3Object.DeletingAnObject(bucketName, key);
    }

    private static void isExistBucket(String bucketName) {
        // 创建桶
        if (!S3Bucket.HasBucket(bucketName)) {
            S3Bucket.CreatingBucket(bucketName);
            System.out.println("Successful create bucket: " + bucketName + "\n");
        } else {
            S3Bucket.HeadBuckte(bucketName);
            System.out.println("Bucket " + bucketName + " is exists, No need to ceate it!\n");
        }
    }

    public static void show() {
        try {
            // 创建桶
            if (!S3Bucket.HasBucket(bucketName)) {
                S3Bucket.CreatingBucket(bucketName);
                System.out.println("Successful create bucket: " + bucketName + "\n");
            } else {
                S3Bucket.HeadBuckte(bucketName);
                System.out.println("Bucket " + bucketName + " is exists, No need to ceate it!\n");
            }

            // 获取桶列表
            List<Bucket> buckets = S3Bucket.ListBuckets();
            System.out.println("桶列表：");
            for (Bucket bucket : buckets) {
                System.out.println("  " + bucket.getName());
            }

            // 整体上传
            System.out.println(new Date().toString());
            System.out.println("Begin to put object \"" + UploadFile + "\" by putObject.");
            File file1 = new File(UploadFile);
            S3Object.PutObject(bucketName, fileKey, file1);

            System.out.println("Successful put object \"" + fileKey + "\" by putObject.\n");
            System.out.println(new Date().toString());

            // 列出所有未完成的分段上传
            System.out.println("列出所有未完成的分段上传:");
            MultipartUploadListing multiUpList = S3Bucket.listMultipartUploads(bucketName);
            for (MultipartUpload upload : multiUpList.getMultipartUploads()) {
                System.out.println("Key:" + upload.getKey());
                System.out.println("Owner:" + upload.getOwner().toString());
                System.out.println("UpLoadID:" + upload.getUploadId());
                System.out.println("Time:" + upload.getInitiated().toString() + "\n");
            }

            // 获取对象列表
            System.out.println("获取对象列表(" + bucketName + "): ");
            List<S3ObjectSummary> obj_list = S3Object.ListingObjects(bucketName);
            if (obj_list != null && obj_list.size() > 0) {
                for (S3ObjectSummary obj_summary : obj_list) {
                    System.out.println("  " + obj_summary.getKey());
                }
                System.out.println();
            }

            // 读取对象
            String getFile = UploadFile + "_new";
            S3Object s3object = S3Object.getObject(bucketName, fileKey);
            System.out.println("Get object: " + UploadFile + " as " + getFile);
            XskyS3Basic.WriteNewFile(s3object.getObjectContent(), getFile);
            s3object.close();

            // 删除对象
//        	List<DeleteObjectsRequest.KeyVersion> listKeys = new ArrayList<DeleteObjectsRequest.KeyVersion>();
//        	listKeys.add(new DeleteObjectsRequest.KeyVersion(UploadFile));
//        	S3Object.deleteObjectS(bucketName, listKeys);
//        	
//            // 删除桶
//        	System.out.println("Begin delete bucket: " + bucketName + ".\n");
//        	S3Bucket.DeletingBucket(bucketName);      	
//        	System.out.println("Finish!"); 

        } catch (AmazonServiceException ase) {
            System.out.println("Caught an AmazonServiceException, which" + " means your request made it "
                    + "to Amazon S3, but was rejected with an error response" + " for some reason.");
            System.out.println("Error Message:    " + ase.getMessage());
            System.out.println("HTTP Status Code: " + ase.getStatusCode());
            System.out.println("AWS Error Code:   " + ase.getErrorCode());
            System.out.println("Error Type:       " + ase.getErrorType());
            System.out.println("Request ID:       " + ase.getRequestId());
        } catch (AmazonClientException ace) {
            System.out.println("Caught an AmazonClientException, which means" + " the client encountered "
                    + "an internal error while trying to " + "communicate with S3, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message: " + ace.getMessage());
        } catch (IllegalArgumentException e) {
            System.out.println("Caught an IllegalArgumentException, Maybe you input a wrong argument.");
            System.out.println("Error Message:	" + e.getMessage());
        } catch (IOException e) {
            System.out.println("Error Message:	" + e.getMessage());
        }
    }

    public static void uploadObjectForInputStream(String bucketName, String key, byte[] bytes, ObjectMetadata metadata) throws SdkClientException {
        isExistBucket(bucketName);
        PutObjectResult result = S3Object.PutObject(bucketName, key, bytes, metadata);
        System.out.println(result);
    }

    public static void uploadObjectForInputStream(String bucketName, String key, InputStream inputStream, ObjectMetadata metadata) throws SdkClientException {
        isExistBucket(bucketName);
        PutObjectResult result = S3Object.PutObject(bucketName, key, inputStream, metadata);
        System.out.println(result);
    }

    public static void downloadObjectThrows(String bucketName, String key, String newFile) throws SdkClientException, IOException {
        isExistBucket(bucketName);
        S3Object s3object = S3Object.getObjectThrows(bucketName, key);
        XskyS3Basic.WriteNewFile(s3object.getObjectContent(), newFile);
        s3object.close();
    }

    public static void copyObjectThrows(String sourceBucketName, String sourceKey, String destinationBucketName, String destinationKey, ObjectMetadata metadata) throws SdkClientException {
        S3Object.copyObejectThrows(sourceBucketName, sourceKey, destinationBucketName, destinationKey, metadata);
    }
}